<template>
    <div class="goods-sku" v-for="item in goods.specs" :key="item.name">
        <dl>
            <dt>{{ item.name }}</dt>
            <dd>
                <template v-for="val in item.values">
                    <img v-if="val.picture" @click="clickSpecs(item, val)" :class="{ selected: val.selected }"
                        :title="val.name" :src="val.picture">
                    <span v-else :class="{ selected: val.selected }" @click="clickSpecs(item, val)">{{ val.name
                        }}</span>
                </template>
            </dd>
        </dl>
    </div>
</template>
<script>
import getPowerSet from '@/vender/power-set'
const spliter = '♥'
//根据skus得到路径字典对象  --- 方法
const getPathMap = (skus) => {
    //声明一个路径字典对象
    const pathMap = {}
    skus.forEach((sku) => {
        //库存大于零
        if (sku.inventory > 0) {
            //组合成 sku属性值 数组
            const skuArr = sku.specs.map(val => val.valueName)
            //通过powerSet算法得到sku属性值数组的子集
            const powerSet = getPowerSet(skuArr)
            //生成路径字典
            powerSet.forEach(set => {
                const key = set.join(spliter)
                if (pathMap[key]) {
                    pathMap[key].push(sku.id)
                } else {
                    pathMap[key] = [sku.id]
                }
            })
        }
    })
    // console.log('路径字典:',pathMap)
    return pathMap
}

//getSelectedArr  得到当前选中规格集合  循环每一行 把选中的按钮 push 到数组中 若一行中没有选中 则为undefined
const getSelectedArr = (specs) => {
    const arr = [] //['粉色',37]
    // console.log('specs', specs)
    specs.forEach((spec, i) => {
        // item.values.forEach(val => {
        //     arr.push(val.selected ? val.name : undefined)
        // })
        const selectedVal = spec.values.find(v => v.selected)
        // console.log(`规格:第${i}行：`,selectedVal)  
        arr.push(selectedVal ? selectedVal.name : undefined)
    })

    return arr
}

//updateDisabledStatus  更新当前 按钮禁用状态
const updateDisabledStatus = (specs, pathMap) => {
    specs.forEach((spec, index) => {//每一行
        const selectedArr = getSelectedArr(specs) //['粉色',37]  返回每行是否选中商品 及 选中商品的名称规格
        // console.log('selectedArr :', selectedArr)
        spec.values.forEach(val => {
            if (val.name === selectedArr[index]) return //已经选中
            //未选中 则添加到数组对应下标中 每一项去路径字典查询有无货
            selectedArr[index] = val.name
            const key = selectedArr.filter(v => v).join(spliter)
            val.disabled = !pathMap[key]
        })
    })
}

//初始化选中的商品(根据skuId)   
// ***** 注释: 数据结构
// ***** specs数组: 每个的商品规格  [{id:string,name:string,values:[{name:string,picture:string,desc:string},{},{},...]},{},...]
// ***** skus数组:  后台返回的sku数据集合 包含id 库存 原价现价 及对应的规格  sku: {id,price,oldPrice,inventory,specs:[{name:'',valueName},{}]}
const initSelectedStatus = (goods, skuId) => {
    //找到父组件传进来的商品skuid
    const sku = goods.skus.find(sku => sku.id === skuId)
    if (sku) {
        //如果通过skuid找到对应商品sku
        goods.specs.forEach((item, i) => {
            item.values.forEach(val => {
                if (val.name === sku.specs[i].valueName) val.selected = true
            })
        })
    }
}

export default {
    name: 'GoodsSku',
    emits: ['changeSku'],
    props: {
        goods: {
            type: Object,
            default: () => { }
        },
        skuId: {
            type: String,
            default: ''
        }
    },
    setup(props, { emit }) {
        //初始化按钮状态 初始化选中的商品(根据skuId)  
        initSelectedStatus(props.goods, props.skuId)
        //生成路径字典
        const pathMap = getPathMap(props.goods.skus)
        //根据路径字典 更新按钮禁用状态
        updateDisabledStatus(props.goods.specs, pathMap)
        //按钮选择与否
        const clickSpecs = (item, val) => {
            console.log('skus :', props.goods.skus)
            console.log('specs :', props.goods.specs)
            if (val.selected) {
                val.selected = false
                return
            } else {
                item.values.forEach(ele => {
                    ele.selected = false
                })
            }
            val.selected = true
            updateDisabledStatus(props.goods.specs, pathMap)
            //getSelectedArr 获取选中的数据 过滤掉undefined
            const selectedArr = getSelectedArr(props.goods.specs).filter(v => v)
            if (selectedArr.length === props.goods.specs.length) {
                const skuIds = pathMap[selectedArr.join(spliter)]
                const sku = props.goods.skus.find(sku => sku.id === skuIds[0])
                // 传递
                emit('changeSku', {
                    skuId: sku.id,
                    price: sku.price,
                    oldPrice: sku.oldPrice,
                    inventory: sku.inventory,
                    specsText: sku.specs.reduce((p, n) => `${p} ${n.name}：${n.valueName}`, '').replace(' ', '')
                })
            } else {
                emit('changeSku', {})
            }

        }
        getPathMap(props.goods.skus)
        return {
            clickSpecs
        }
    }
}
</script>
<style scoped lang="less">
.sku-state-mixin () {
    border: 1px solid #e4e4e4;
    margin-right: 10px;
    cursor: pointer;

    &.selected {
        border-color: @xtxColor;
    }

    &.disabled {
        opacity: 0.6;
        border-style: dashed;
        cursor: not-allowed;
    }
}

.goods-sku {
    padding-left: 10px;
    padding-top: 20px;

    dl {
        display: flex;
        padding-bottom: 20px;
        align-items: center;

        dt {
            width: 50px;
            color: #999;
        }

        dd {
            flex: 1;
            color: #666;

            >img {
                width: 50px;
                height: 50px;
                .sku-state-mixin ();
            }

            >span {
                display: inline-block;
                height: 30px;
                line-height: 28px;
                padding: 0 20px;
                .sku-state-mixin ();
            }
        }
    }
}
</style>